package org.budo.dubbo.protocol.http.authentication;

import java.lang.reflect.Method;

import org.budo.dubbo.protocol.http.aop.permission.user.UserPermissionCheck;
import org.budo.dubbo.protocol.http.util.BudoReflectionUtil;
import org.budo.support.lang.util.ReflectUtil;
import org.budo.support.spring.context.aware.BudoApplicationContextAware;
import org.springframework.web.method.HandlerMethod;

/**
 * @author limingwei
 */
public class AuthenticationCheckUtil {
    private static final String SSO_CALLBACK = "com.taojin.account.web.api.config.TaojinAccountSsoCallback";

    public static Boolean requireAuthenticationCheck_aop(Class<?> interfaceType, Method method) {
        if (ReflectUtil.hasClass(SSO_CALLBACK)) {
            Class ssoCallbackType = ReflectUtil.classForName(SSO_CALLBACK);
            if (ssoCallbackType.isAssignableFrom(interfaceType)) {
                return false; // 不需要token认证
            }
        }

        AuthenticationCheck methodAnnotation = BudoReflectionUtil.getMethodAnnotation(interfaceType, //
                method.getName(), //
                method.getParameterTypes(), //
                AuthenticationCheck.class);

        if (null != methodAnnotation) {
            return methodAnnotation.requires();
        }

        AuthenticationCheck typeAnnotation = interfaceType.getAnnotation(AuthenticationCheck.class);
        if (null != typeAnnotation) {
            return typeAnnotation.requires();
        }

        return defaultAuthenticationCheck_aop();
    }

    /**
     * 判断是否需要检查
     */
    public static Boolean requireAuthenticationCheck_mvc(HandlerMethod handlerMethod) {
        AuthenticationCheck methodAnnotation = handlerMethod.getMethodAnnotation(AuthenticationCheck.class);
        if (null != methodAnnotation) {
            return methodAnnotation.requires();
        }

        AuthenticationCheck typeAnnotation = handlerMethod.getBeanType().getAnnotation(AuthenticationCheck.class);
        if (null != typeAnnotation) {
            return typeAnnotation.requires();
        }

        // 没有添加 @AuthenticationCheck 注解时
        if (null != handlerMethod.getMethodAnnotation(UserPermissionCheck.class)) {
            return true;
        }

        return defaultAuthenticationCheck_mvc();
    }

    private static Boolean defaultAuthenticationCheck_aop() {
        AuthenticationCheckMethodInterceptor methodInterceptor = BudoApplicationContextAware.getBeanCached_2(AuthenticationCheckMethodInterceptor.class);
        if (null != methodInterceptor) {
            return methodInterceptor.getDefaultAuthenticationCheck();
        }

        return false;
    }

    private static Boolean defaultAuthenticationCheck_mvc() {
        AuthenticationCheckHandlerInterceptor handlerInterceptor = BudoApplicationContextAware.getBeanCached(AuthenticationCheckHandlerInterceptor.class);
        if (null != handlerInterceptor) {
            return handlerInterceptor.getDefaultAuthenticationCheck();
        }

        return false;
    }
}